home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 46
/
Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso
/
-in_the_mag-
/
synth_studies
/
resgrep03b
/
source
/
resgrep.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-15
|
12KB
|
418 lines
//
// ResGrep -- Programm zum nutzen von Mac-Resourcen auf dem Amiga
//
// 22.03.1992 Andre geschrieben
//
extern "C" {
#include <exec/types.h>
#include <clib/asl_protos.h>
#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/intuition_protos.h>
};
#include "resources.h"
#include "utils.h"
#include "export.h"
struct IntuitionBase *IntuitionBase = NULL;
struct GadToolsBase *GadToolsBase = NULL;
struct AslBase *AslBase = NULL;
struct IFFParseBase *IFFParseBase = NULL;
struct Screen *theScreen = NULL;
struct Window *theWindow = NULL; // Das Hauptfenster
APTR VisualInfo = NULL;
struct Menu *Menus = NULL;
struct FileRequester *fr = NULL; // Mein FileRequester
struct MsgPort *up = NULL; // Mein UserPort
list FileList; // Hier stehen alle Files drin
FILE *globalFile; // Das aktuelle File
bool AutoSave = true; // Ist AutoSave gewählt?
extern list *conversions; // Die Umwandlungsmethoden
// Diese Funktion gibt die FileListe frei.
// Dies MUSS expiziet vor dem Ende des Programms geschehen, da Routinen der
// 'intuition.library' zum schliessen der Fenster verwandt werden.
void freeFileList(void)
{
node *n;
while( (n=FileList.remhead())!=NULL )
delete ((ResFile *)n);
FileList.closedis();
return;
}
// Räumt auf.
// Auch diese Funktion muß expliziet vor Ende des Programms aufgerufen
// werden. (Begründung: siehe oben)
void CleanUp(void)
{
struct Library *ml;
// Es müssen Expliziet die Fenster geschlossen werden
// da der Destruktor sonst die Libraries benötigt!
freeFileList();
if(fr) FreeFileRequest(fr);
if(Menus) FreeMenus( Menus );
if(up) {RemPort(up); DeleteMsgPort(up); }
if(VisualInfo) FreeVisualInfo( VisualInfo );
if(theScreen) UnlockPubScreen( 0l, theScreen );
if(IntuitionBase) {ml=(struct Library *)IntuitionBase; CloseLibrary(ml); }
if(GadToolsBase) { ml=(struct Library *)GadToolsBase; CloseLibrary(ml); }
if(AslBase) { ml=(struct Library *)AslBase; CloseLibrary(ml); }
if(IFFParseBase) { ml=(struct Library *)IFFParseBase; CloseLibrary(ml); }
return;
}
// Das Hauptprogramm
// Hier findet so gut wie alles statt und hier gibt es auch die
// MainEventLoop.
int main(void)
{
node *theNode, *n;
struct IntuiMessage theIMsg, *imsg;
int ret;
int portnum=0; // Der Name und die Numer des
char portname[25]; // (ARexx-) Ports.
// Elemente aus GadToolsBox:
struct TextAttr topaz8 =
{
( STRPTR )"topaz.font", 8, 0x00, 0x01
};
struct NewMenu NewMenu[] =
{
NM_TITLE,(UBYTE *)"Project", 0l, 0, 0, 0l,
NM_ITEM, (UBYTE *)"Open...", (UBYTE *)"O", 0, 0, 0l,
NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
NM_ITEM, (UBYTE *)"Print", (UBYTE *)"P", NM_ITEMDISABLED, 0, 0l,
NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
NM_ITEM, (UBYTE *)"Hide", 0l, 0, 0, 0l,
NM_SUB, (UBYTE *)"Window", 0l, 0, 0, 0l,
NM_SUB, (UBYTE *)"Child Windows", 0l, 0, 0, 0l,
NM_SUB, (UBYTE *)"All Windows", 0l, 0, 0, 0l,
NM_ITEM, (UBYTE *)"Reveal", 0l, 0, 0, 0l,
NM_SUB, (UBYTE *)"Child Windows", 0l, 0, 0, 0l,
NM_SUB, (UBYTE *)"All Windows", 0l, 0, 0, 0l,
NM_ITEM, (UBYTE *)"Close", (UBYTE *)"K", 0, 0, 0l,
NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
NM_ITEM, (UBYTE *)"About...", 0l, 0, 0, 0l,
NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
NM_ITEM, (UBYTE *)"Quit ResGrep...", (UBYTE *)"Q", 0, 0, 0l,
NM_TITLE, (UBYTE *)"Settings", 0l, 0, 0, 0l,
NM_ITEM, (UBYTE *)"Autosave Settings?", 0l, CHECKIT|CHECKED, 0, 0l,
NM_ITEM, (UBYTE *)"Create Icons?", 0l,
NM_ITEMDISABLED|CHECKIT|CHECKED, 0, 0l,
NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
NM_ITEM, (UBYTE *)"Edit Conversions...", (UBYTE *)"E", 0, 0, 0l,
NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
NM_ITEM, (UBYTE *)"Load Settings...", 0l, 0, 0, 0l,
NM_ITEM, (UBYTE *)"Save Settings", 0l, 0, 0, 0l,
NM_ITEM, (UBYTE *)"Save Settings As...", 0l, 0, 0, 0l,
NM_END, 0l, 0l, 0, 0l, 0l
};
// Öffne die Intuition-library als erste, damit ich dann wenigstens
// bei den anderen Libraries Fehler anzeigen kann.
if( (IntuitionBase=(struct IntuitionBase *)
OpenLibrary((UBYTE *)"intuition.library",37))==NULL )
{
// Was soll ich tun?!?
// printf("Kann IntuitionLibrary nicht öffnen.\n");
CleanUp();
return 2;
}
if( (GadToolsBase=(struct GadToolsBase *)
OpenLibrary((UBYTE *)"gadtools.library",37))==NULL )
{
ResError("Can't open 'gadtools.library'.");
CleanUp();
return 1;
}
if( (AslBase=(struct AslBase *)
OpenLibrary((UBYTE *)"asl.library",37))==NULL )
{
ResError("Can't open 'asl.library'.");
CleanUp();
return 3;
}
if( (IFFParseBase=(struct IFFParseBase *)
OpenLibrary((UBYTE *)"iffparse.library",37))==NULL )
{
ResError("Can't open 'iffparse.library'.");
CleanUp();
return 3;
}
if( (fr=(struct FileRequester *)AllocFileRequest())== NULL )
{
ResError("Can't alloc file requester.");
CleanUp();
return 4;
}
if ( NOT( theScreen = LockPubScreen( (UBYTE *)"Workbench" )))
{
ResError("Can't lock the Workbench Screen.");
CleanUp();
return 5;
}
if ( NOT( VisualInfo = GetVisualInfo( theScreen, TAG_DONE )))
{
ResError("Can't get Visualinfo.");
CleanUp();
return 6;
}
if ( NOT( Menus = CreateMenus( NewMenu, GTMN_FrontPen, 0l, TAG_DONE )))
{
CleanUp();
return 7;
}
LayoutMenus( Menus, VisualInfo, GTMN_TextAttr, &topaz8, TAG_DONE );
// Da ich jetzt kein 'echtes' MainWindow mehr habe, muß ich mich
// selbst um solche Dinge wie MessagePorts kümmern.
if( (up=CreateMsgPort())==NULL )
{
ResError("Can't create message port.");
CleanUp();
return 8;
}
// Diese folgende Schleife sucht den ersten Namen (laut AUIG) für einen
// Message Port für ResGrep.
do
{
// Portnamen herrichten
portnum++;
sprintf(portname,"RESGREP.%d",portnum);
// printf("Name: '%s' Find: %d\n",portname,FindPort((UBYTE*)portname));
// Und nachsehen, ob er schon existiert.
} while( FindPort((UBYTE*)portname)!=NULL );
up->mp_Node.ln_Name = portname;
up->mp_Node.ln_Pri = 0;
AddPort(up);
// Die Liste, die zum exportieren der Daten notwendig ist (hier steht
// drin wie und wohin sie exporttert werden) wird angelegt.
initexport();
// Die alten Einstellungen werden geladen.
loadsettings();
// Das HauptWindow (jetzt das FileWindow) öffnen
FileList.display(up,Menus,readwrite,"pn",35,7, NewXPos(),NewYPos(),
"ResGrep - FileList", "ResGrep");
CoordsUsed();
theWindow=FileList.getwin();
// Das erste File öffnen (was soll mit einem leeren MainWindow geschehen?)
{
ResFile *rf=new ResFile();
if( rf->open()==0 )
{
// Das Element einketten (safely!)
FileList.start_change();
FileList.addtail(rf);
FileList.end_change();
}
else
delete rf;
}
// Und ab hier die sagenumwobene, in der sich alles abspielende
// MainEventLoop!
for(;;) {
Wait( 1UL<<(unsigned long)(up->mp_SigBit) );
while( (imsg=GT_GetIMsg(up)) != NULL )
{
// Message kopieren und sofort orginale sofort zurückschicken.
theIMsg=*imsg;
GT_ReplyIMsg(imsg);
// Zuerst einmal alle Messages abfangen, die nicht an ein
// Fenster weitergegeben werden sollen. Dazu zählen z.B. alle
// Menuauswahlen.
switch( theIMsg.Class )
{
case IDCMP_INTUITICKS:
break;
case IDCMP_MENUPICK:
{
int MenuNumber=theIMsg.Code;
struct MenuItem *Item;
// Die Menueaufwahl: es wird auch der Fall des mehrfachen
// auswählens berücksichtigt.
while( MenuNumber!=MENUNULL )
{
Item=ItemAddress(Menus,MenuNumber);
switch( MENUNUM(MenuNumber) )
{
case 0:
switch( ITEMNUM(MenuNumber) )
{
case 0: // Open...
{
ResFile *rf=new ResFile();
if( rf->open()==0 )
{
// Das Element einketten (safely!)
FileList.start_change();
FileList.addtail(rf);
FileList.end_change();
break;
}
else
delete rf;
}
break;
// 1 - BarLab
case 2: // Print
ResWarning("Print\nNot implemented yet.");
break;
// 3 - BarLab
case 4: // Hide
switch( SUBNUM(MenuNumber) )
{
case 0: // Hide >> Window
for(n=FileList.getfirst();
n->getsucc();n=n->getsucc())
((ResFile *)n)->hidewin(&theIMsg);
break;
case 1: // Hide >> Child Windows
{
struct IntuiMessage *im=&theIMsg;
if( theIMsg.IDCMPWindow==FileList.getwin() )
im=NULL;
for(n=FileList.getfirst();
n->getsucc();n=n->getsucc())
((ResFile *)n)->hidechild(im);
}
break;
case 2: // Hide >> All Windows
for(n=FileList.getfirst();n->getsucc();
n=n->getsucc())
((ResFile *)n)->hidechild(NULL);
break;
}
break;
case 5: // Reveal
switch( SUBNUM(MenuNumber) )
{
case 0: // Reveal >> Child Windows
for(n=FileList.getfirst();
n->getsucc();n=n->getsucc())
((ResFile *)n)->revealchild(&theIMsg);
break;
case 1: // Reveal >> All Windows
for(n=FileList.getfirst();
n->getsucc();n=n->getsucc())
((ResFile *)n)->revealchild(NULL);
break;
}
break;
case 6: // Close
for(n=FileList.getfirst(); n->getsucc(); n=n->getsucc())
((ResFile *)n)->closewin(&theIMsg);
break;
// 7 - BarLab
case 8: // About...
ResMessage("ResGrep\n"
"Version 0.3 beta\n"
"copyright 1992 by Andreas Florath");
break;
// 9 - BarLab
case 10: // Quit...
CleanUp();
return 0;
break;
default:
ResError("Fatal:\nUnknown menu item.");
break;
}
break;
case 1:
switch( ITEMNUM(MenuNumber) )
{
case 0:
AutoSave = AutoSave ? false : true;
break;
case 3:
editconv();
if( AutoSave )
savesettings();
break;
case 5:
loadsettings();
break;
case 6:
savesettings();
break;
case 7:
savesettingsas();
break;
default:
ResError("Fatal:\nUnknown menu item");
break;
}
break;
default:
ResError("Fatal:\nUnknown menu");
break;
}
MenuNumber=Item->NextSelect;
} // End: while( MenuNumber!=MENUNULL ) ...
} // End: case IDCMP_MENUPICK
break;
default: // In allen anderen Fällen wurde ein Fenster angeklickt
{
node *theNode;
// Ist es für das MainWindow?
if( theIMsg.IDCMPWindow==FileList.getwin() )
{
switch(theIMsg.Class)
{
case IDCMP_CLOSEWINDOW:
theIMsg.IDCMPWindow=NULL;
CleanUp();
return 0;
}
}
theNode=FileList.checkdis(&theIMsg);
if( theIMsg.IDCMPWindow==NULL )
{
if( theNode==NULL )
break;
((ResFile *)theNode)->displaywin(up,Menus);
break;
}
// War ein anderes Fenster gemeint?
for(node *n=FileList.getfirst(); n->getsucc(); n=n->getsucc())
{
globalFile= ((ResFile *)n)->getfp();
theNode = ((ResFile *)n)->check(&theIMsg);
}
}
break;
}
} // End: while( GetIMsg()!=NULL ) ...
} // ForEver - Never
CleanUp(); // Im Falle eines Falles...
return 0;
}